import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

import { TreadstoneService } from '@/common/services/treadstone.service';
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';

import { AppLogger } from './logger.service';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  constructor(
    private readonly logger: AppLogger,
    private readonly treadstone: TreadstoneService,
  ) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    const response = context.switchToHttp().getResponse();
    const { method, originalUrl, headers } = request;
    const userAgent = headers['user-agent'] || '';
    const ipaddress = headers['x-real-ip'] || '';
    const now = Date.now();

    return next.handle().pipe(
      tap(() => {
        const contentLength = response.get('content-length') || 0;
        const duration = Date.now() - now;
        if (request.user) {
          const action = request.path.split('/').at(-1);
          if (!['all', 'where', 'page', 'first', 'unique'].includes(action)) {
            this.treadstone.createOperation({
              method,
              name: '系统操作日志',
              scene: 'RequestLog',
              path: request.path,
              creatorId: request.user.serial,
              creatorName: request.user.name,
              payload: request.body,
            });
          }
        }
        if (process.env.NODE_ENV === 'development') {
          this.logger.log(`[${method}] ${originalUrl} ${response.statusCode} - ${duration}ms ${contentLength}`);
        } else {
          this.logger.log(
            `[${method}] ${originalUrl} ${response.statusCode} - ${duration}ms ${contentLength} ${ipaddress} - ${userAgent}`,
          );
        }
      }),
    );
  }
}
